import { KANBAN_RECT_TYPE } from './constants';

/**
 * 尺寸的计算方式
 * @param {Object} rect
 * @param {string} rect.type
 * @param {number} rect.width
 * @param {number} rect.height
 */
export function getKanbanStyleByRect (rect) {
  switch (rect.type) {
    case KANBAN_RECT_TYPE.custom.value: {
      return {
        width: `${rect.width}px`,
        height: `${rect.height}px`
      };
    }
    case KANBAN_RECT_TYPE.auto.value: {
      return {
        width: `${rect.width}%`,
        height: `${rect.height}%`
      };
    }
    case KANBAN_RECT_TYPE.ratio.value: {
      return {
        paddingBottom: `${rect.height / rect.width * 100}%`
      };
    }
  }
}

/**
 * 过滤对象的无效值
 * @param {Object} obj
 * @return {{}}
 */
export function filterInvalidValue (obj) {
  const newObj = {};
  // eslint-disable-next-line no-unused-vars
  for (const key in obj) {
    const value = obj[key];
    if (!validValue(value)) {
      continue;
    }
    newObj[key] = value;
  }
  return newObj;
}

/**
 * 检测值是否是一个有效的
 * @param {Array | number | string} val
 * @return boolean true 有效，false 无效
 */
export function validValue (val) {
  return !((Array.isArray(val) && val.length === 0) || [0, '', void 0, null].includes(val));
}

/**
 * 回滚到目标位置，是根据窗口位置进行移动的
 * @param {number} [targetPosition = 0] 目标位置
 * @param {HTMLBaseElement | Element} [element = window]
 * @param {number} [backTime = 200] 滚动时间
 */
let isMoving = false; // 是否正在移动
const MIN_TIME = 50; // 最小时间
let intervalTask = null;
export function backToTargetPosition (
  { targetPosition = 0, element = window, backTime = 200 } = {}
) {
  if (isMoving) return;
  if (backTime <= MIN_TIME) {
    // 不需要动画，直接回滚
    return element.scrollTo(0, targetPosition);
  }
  const start = element.pageYOffset;
  let i = 0;
  isMoving = true;
  const isDown = start > targetPosition;
  intervalTask = setInterval(() => {
    const next = Math.floor(_easeInOutQuad(10 * i, start, (isDown ? -start : targetPosition), backTime));
    if ((isDown ? next <= targetPosition : next >= targetPosition)) {
      element.scrollTo(0, targetPosition);
      clearInterval(intervalTask);
      isMoving = false;
    } else {
      element.scrollTo(0, next);
    }
    i++;
  }, 16.7);
}
/**
 * 动画曲线
 * @param {number} t 保存动画开始的指定时间。例如，如果t的值为0，则表示动画刚刚开始。
 * @param {number} b 保存对象在x轴上的指定起始位置。例如，如果b的值为10，则表示对象在x坐标上的起始位置为10。
 * @param {number} c 保存对象的指定值更改。例如，如果c的值为30，则意味着对象必须向右移动30，以40结尾。
 * @param {number} d 保留整个过程的指定持续时间。例如，如果d的值为2，则表示对象有2秒的时间来执行从10到40的运动。
 * @return {number} 此方法返回对象的缓和位置，即对象在特定时间的位置
 */
function _easeInOutQuad (t, b, c, d) {
  if ((t /= d / 2) < 1) return c / 2 * t * t + b;
  return -c / 2 * (--t * (t - 2) - 1) + b;
}

/**
 * 生成随机数作为 data 的唯一标识
 * @return {string}
 */
export function generateRandomNumber () {
  return (
    (Math.random() * 10000000).toString(16).substr(0, 4) +
    '-' +
    new Date().getTime() +
    '-' +
    Math.random().toString().substr(2, 5)
  );
}

/**
 * 将数组转成对象
 * @param {Array} arr
 * @param {Object} [opt]
 * @param {string} [opt.prop]
 * @return {*}
 */
export function arrayToObject (arr, opt) {
  opt = Object.assign({
    prop: 'id'
  }, opt);
  return arr.reduce((obj, item) => {
    obj[item[opt.prop]] = item;
    return obj;
  }, {});
}
